package com.ikun.admin.modules.gen.iservice.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ikun.admin.modules.gen.entity.FieldType;
import com.ikun.admin.modules.gen.entity.Table;
import com.ikun.admin.modules.gen.entity.TableEntity;
import com.ikun.admin.modules.gen.iservice.IFieldTypeService;
import com.ikun.admin.modules.gen.service.FieldTypeService;
import com.ikun.admin.modules.gen.service.TableEntityService;
import com.ikun.admin.modules.gen.service.TableService;
import com.ikun.admin.modules.gen.vo.FieldListParamVo;
import com.ikun.admin.modules.gen.vo.FieldTypeCommonVo;
import com.ikun.common.exception.MyException;
import com.ikun.common.result.Result;
import com.ikun.common.search.PageData;
import com.ikun.common.search.PageResult;
import com.ikun.common.search.build.QueryBuilder;
import com.ikun.common.search.build.ResultBuilder;
import com.ikun.common.utils.DataCopy;
import com.ikun.common.validate.group.AddGroup;
import com.ikun.common.validate.group.UpdateGroup;
import com.ikun.common.validate.validator.ValidateExecutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName IFieldTypeServiceImpl
 * @Description:
 * @CreateDate: 2024/4/16 9:08
 */
@Service
public class IFieldTypeServiceImpl implements IFieldTypeService {

    @Autowired
    private FieldTypeService fieldTypeService;

    @Autowired
    private TableEntityService tableEntityService;

    @Autowired
    private TableService tableService;

    @Override
    @Transactional
    public Result<String> fieldTypeAddOrUpdate(FieldTypeCommonVo fieldTypeCommonVo) {
        if (Objects.isNull(fieldTypeCommonVo.getId())) {
            ValidateExecutor.execute(fieldTypeCommonVo, AddGroup.class);
            FieldType fieldType = DataCopy.copyToObj(fieldTypeCommonVo, FieldType.class);
            fieldTypeService.save(fieldType);
        } else {
            ValidateExecutor.execute(fieldTypeCommonVo, UpdateGroup.class);
            // 获取修改之前的类型值
            FieldType updateBeforeFieldType = fieldTypeService.getById(fieldTypeCommonVo.getId());
            fieldTypeService.update(new UpdateWrapper<FieldType>().lambda().eq(FieldType::getId, fieldTypeCommonVo.getId())
                    .set(FieldType::getFieldLabel, fieldTypeCommonVo.getFieldLabel())
                    .set(FieldType::getFieldValue, fieldTypeCommonVo.getFieldValue())
                    .set(FieldType::getTypeLength, fieldTypeCommonVo.getTypeLength())
                    .set(FieldType::getTypeHold, fieldTypeCommonVo.getTypeHold()));
            if (!Objects.equals(updateBeforeFieldType.getFieldValue(), fieldTypeCommonVo.getFieldValue())) {
                // 修改tableEntity中的字段类型值
                tableEntityService.update(new UpdateWrapper<TableEntity>()
                        .lambda()
                        .eq(TableEntity::getFieldValue, updateBeforeFieldType.getFieldValue())
                        .set(TableEntity::getFieldValue, fieldTypeCommonVo.getFieldValue()));
            }

        }
        return new Result<String>().success("操作成功");
    }

    @Override
    public Result<PageResult<FieldTypeCommonVo>> fieldTypeList(PageData<FieldListParamVo> pageData) {
        PageData.PageParam pageParam = pageData.getPageParam();

        Integer current = pageParam.getCurrent();
        Integer size = pageParam.getSize();
        IPage<FieldType> page = new Page<FieldType>().setCurrent(current).setSize(size);
        FieldListParamVo fieldListParamVo = pageData.getCondition();

        QueryWrapper<FieldType> fieldTypeQueryWrapper = new QueryWrapper<>();

        Boolean build = QueryBuilder.build(fieldTypeQueryWrapper, fieldListParamVo);
        if (!build) {
            return new Result<PageResult<FieldTypeCommonVo>>().success(PageResult.emptyPageResult());
        }
        fieldTypeService.page(page, fieldTypeQueryWrapper);

        List<FieldTypeCommonVo> fieldTypeCommonVoList = new ArrayList<>();
        if (page.getRecords().size() > 0) {
            ResultBuilder.buildResult(page.getRecords(), fieldTypeCommonVoList, FieldTypeCommonVo.class);
        }
        return new Result<PageResult<FieldTypeCommonVo>>().success(PageResult.getInstance(page.getTotal(), fieldTypeCommonVoList));
    }

    @Override
    public Result<List<FieldTypeCommonVo>> fieldTypeDict() {

        List<FieldType> fieldTypeList = fieldTypeService.list(new QueryWrapper<>());

        List<FieldTypeCommonVo> fieldTypeCommonVoList = DataCopy.copyToListObj(fieldTypeList, FieldTypeCommonVo.class);

        return new Result<List<FieldTypeCommonVo>>().success(fieldTypeCommonVoList);
    }

    @Override
    @Transactional
    public Result<String> fieldTypeDelete(Long id) {
        FieldType fieldType = fieldTypeService.getById(id);
        String fieldValue = fieldType.getFieldValue();
        //查询是否有使用该类型的表
        List<TableEntity> tableEntityList = tableEntityService.list(new QueryWrapper<TableEntity>().lambda().eq(TableEntity::getFieldValue, fieldValue));
        if (Objects.nonNull(tableEntityList) && tableEntityList.size() > 0) {
            Set<Long> tableIdSet = tableEntityList.stream().map(item -> item.getTableId()).collect(Collectors.toSet());
            List<Table> tableList = tableService.list(new QueryWrapper<Table>().lambda().in(Table::getId, tableIdSet));
            List<String> tableNameList = tableList.stream().map(Table::getTableName).collect(Collectors.toList());
            throw new MyException("不能删除该类型,因为该类型下面还有如下表使用了该类型:" + tableNameList);
        }

        fieldTypeService.removeById(id);
        return new Result<String>().success("操作成功");
    }

    @Override
    public Result<FieldTypeCommonVo> fieldTypeDetail(Long id) {
        FieldType fieldType = fieldTypeService.getById(id);

        FieldTypeCommonVo fieldTypeCommonVo = DataCopy.copyToObj(fieldType, FieldTypeCommonVo.class);
        return new Result<FieldTypeCommonVo>().success(fieldTypeCommonVo);
    }

}
